package cn.gov.pbc.gd.credit.core.service.inquiry.impl;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Date;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import javax.servlet.http.HttpServletRequest;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.liu.jbase.ResultVo;
import com.liu.jbase.annotation.LogAnnotation;
import com.liu.jbase.constant.ResCode;
import com.liu.jbase.service.impl.BaseServiceImpl;
import com.liu.tools.DateUtil;
import com.liu.tools.LogUtil;
import com.liu.tools.NetHelper;
import com.liu.tools.PrimaryUtil;
import com.liu.tools.StrUtil;

import cn.gov.pbc.gd.credit.api.corp.ICorpApi;
import cn.gov.pbc.gd.credit.api.inquiry.IInquiryApi;
import cn.gov.pbc.gd.credit.api.inquiry.agent.IAgentApi;
import cn.gov.pbc.gd.credit.api.inquiry.apply.IApplyTblApi;
import cn.gov.pbc.gd.credit.api.inquiry.justice.IJusticeApi;
import cn.gov.pbc.gd.credit.api.log.ILogInquiryApi;
import cn.gov.pbc.gd.credit.api.notice.INoticeApi;
import cn.gov.pbc.gd.credit.center.service.query.ICCQueryService;
import cn.gov.pbc.gd.credit.common.constant.CodeConstant;
import cn.gov.pbc.gd.credit.common.constant.CommonConstant;
import cn.gov.pbc.gd.credit.common.constant.ConfConstant;
import cn.gov.pbc.gd.credit.common.constant.LogConstant;
import cn.gov.pbc.gd.credit.common.model.UserModel;
import cn.gov.pbc.gd.credit.common.service.redis.IRedisService;
import cn.gov.pbc.gd.credit.common.util.UserUtil;
import cn.gov.pbc.gd.credit.core.service.CenterType;
import cn.gov.pbc.gd.credit.core.service.InquiryUtil;
import cn.gov.pbc.gd.credit.core.service.inquiry.IInquiryService;
import cn.gov.pbc.gd.credit.user.service.dictionary.IDictionaryService;
import cn.gov.pbc.gd.credit.user.service.realuser.IRealUserService;
import cn.gov.pbc.gd.credit.vo.center.ResCCUserVo;
import cn.gov.pbc.gd.credit.vo.center.query.ReqCCApplyTblVo;
import cn.gov.pbc.gd.credit.vo.center.query.ReqCCCreditReportVo;
import cn.gov.pbc.gd.credit.vo.center.query.ReqCCJusticeVo;
import cn.gov.pbc.gd.credit.vo.center.query.ReqFirstStepVo;
import cn.gov.pbc.gd.credit.vo.center.query.ReqSecondStepVo;
import cn.gov.pbc.gd.credit.vo.center.query.ResCCApplyTblVo;
import cn.gov.pbc.gd.credit.vo.center.query.ResCCCreditReportVo;
import cn.gov.pbc.gd.credit.vo.center.query.ResCCJusticeVo;
import cn.gov.pbc.gd.credit.vo.center.query.ResFirstStepVo;
import cn.gov.pbc.gd.credit.vo.center.query.ResSecondStepVo;
import cn.gov.pbc.gd.credit.vo.corp.ResCorpVo;
import cn.gov.pbc.gd.credit.vo.dictionary.DictionaryVo;
import cn.gov.pbc.gd.credit.vo.dictionary.ResDictionaryVo;
import cn.gov.pbc.gd.credit.vo.inquiry.InquiryVo;
import cn.gov.pbc.gd.credit.vo.inquiry.ResInquiryVo;
import cn.gov.pbc.gd.credit.vo.inquiry.agent.AgentVo;
import cn.gov.pbc.gd.credit.vo.inquiry.apply.ApplyTblVo;
import cn.gov.pbc.gd.credit.vo.inquiry.apply.ResApplyTblVo;
import cn.gov.pbc.gd.credit.vo.inquiry.justice.JusticeVo;
import cn.gov.pbc.gd.credit.vo.log.LogInquiryVo;
import cn.gov.pbc.gd.credit.vo.notice.NoticeVo;

@Service
public class InquiryServiceImpl extends BaseServiceImpl<ResInquiryVo, InquiryVo, IInquiryApi> implements IInquiryService{

	private static Logger logger = LoggerFactory.getLogger(InquiryServiceImpl.class);
	
	@Autowired
	private IInquiryApi inquiryApi;
	
	@Autowired
	private IAgentApi agentApi;
	
	@Autowired
	private IJusticeApi justiceApi;
	
	@Autowired
	private ICCQueryService ccQueryService;
	
	@Autowired
	private IRedisService redisService;
	
	@Autowired
	private IRealUserService realUserService;
	
	@Autowired
	private INoticeApi noticeApi;
	
	@Autowired
	private ILogInquiryApi logInquiryApi;
	
	@Autowired
	private IApplyTblApi applyTblApi;
	
	@Autowired
	private ICorpApi corpApi;
	
	@Autowired
	private IDictionaryService dictionaryService;
	
	private Executor executor = Executors.newFixedThreadPool(10);
	
	@LogAnnotation(moduleName=LogConstant.MODULE_INQUIRY, option=LogConstant.PERSON_QUERY, logType=LogConstant.LOG_QUERY, content="个人查询信用报告")
	@Override
	public synchronized ResultVo<ResInquiryVo> add(InquiryVo record, HttpServletRequest request) {

		ResultVo<ResInquiryVo> resultVo = new ResultVo<>();
		
		if(record == null || StrUtil.isNull(record.getUserName(), record.getCardNum())){
			
			logger.error(LogUtil.msg("InquiryServiceImpl:add", "请求参数正确"));
			
			resultVo.setCode(CodeConstant.REQ_PARAM_FAIL);
			resultVo.setMsg("请求参数不正确");
			return resultVo;
		}

		UserModel userModel = UserUtil.getUserModel(record.getSid(), redisService);
		
		if(StrUtil.isNull(userModel.getRealUserId())){

			logger.error(LogUtil.msg("InquiryServiceImpl:add", "该账户没有关联真实用"));
			
			resultVo.setCode(CodeConstant.FAIL);
			resultVo.setMsg("该账户没有关联征信中心用户，不能查询，请与管理员联系");
			return resultVo;
		}
		
		if(! checkLimitCount(record.getSid())){
			
			resultVo.setCode(ResCode.FAIL);
			resultVo.setMsg("当天的查询次数超限");
			return resultVo;
		}
		if(StrUtil.isNotNull(redisService.get(record.getCardNum()))){
			resultVo.setCode(ResCode.FAIL);
			resultVo.setMsg("不准在5分钟之内查询同一用户征信信息");
			return resultVo;
		}
		
		record.setInquiryType(CommonConstant.INQUIRY_TYPE_PERSON);
		record.setStatus(1);
		
		ReqFirstStepVo reqFirstStepVo = InquiryUtil.getReqFirstStepVo(record);
		
		ResCCUserVo resCCUserVo = InquiryUtil.getResCCUserVo(request, redisService, realUserService);
		if(StrUtil.isNull(ConfConstant.ccTestPath) && resCCUserVo == null){
			logger.error(LogUtil.msg("InquiryServiceImpl:add", "登录征信中心失败", JSON.toJSONString(record), record.getIp()));
			resultVo.setCode(CodeConstant.FAIL);
			resultVo.setMsg("查询失败（不能登录征信中心）");
			return resultVo;		
		}
		
		if(resCCUserVo != null){
			reqFirstStepVo.setCookies(resCCUserVo.getCookies());
		}
		
		ResultVo<ResFirstStepVo> resultFirstStep = ccQueryService.queryFirstStep(reqFirstStepVo, request);
		
		if(CodeConstant.CREDIT_NO_LOGIN.equals(resultFirstStep.getCode())){
			resCCUserVo = InquiryUtil.loginCCUser(userModel, redisService, realUserService, request);
			if(resCCUserVo != null){
				reqFirstStepVo.setCookies(resCCUserVo.getCookies());
				resultFirstStep = ccQueryService.queryFirstStep(reqFirstStepVo, request);
				
			}
		}
		
		if(! CodeConstant.SUCCESS.equals(resultFirstStep.getCode())){
			
			logger.error(LogUtil.msg("InquiryServiceImpl:add", "查询征信中心失败", JSON.toJSONString(record), record.getIp()));
			resultVo.setCode(resultFirstStep.getCode());
			resultVo.setMsg("请求查询征信中心失败");
			return resultVo;
		}
		
		record.setIsCharge(resultFirstStep.getData().getIsFee());
		record.setInquiryIp(NetHelper.getIpAddr(request));
		try {
			if(StrUtil.isNotNull(record.getId())){
				
				resultVo = super.update(record, request);
			} else {
				record.setDeptId(userModel.getDeptId());
				record.setCorpId(userModel.getCorpId());
				record.setOperationTime(new Date());
				record.setOperatorId(userModel.getUserId());
				
				resultVo = super.add(record, request);
			}
		} catch (Exception e) {
			
			resultVo.setCode(CodeConstant.EXCEPTION);
			resultVo.setMsg("查询失败，添加查询记录出错");
			logger.error(LogUtil.msg("InquiryServiceImpl:add", "添加或更新数据库失败"), e);
			return resultVo;
		}
		
		if(! CodeConstant.SUCCESS.equals(resultVo.getCode())){
			return resultVo;
		}
		
		ResInquiryVo resInquiryVo = new ResInquiryVo();
		resInquiryVo.setId(record.getId());
		resInquiryVo.setFirstStepVo(resultFirstStep.getData());
		
		resultVo.setData(resInquiryVo);
		
		return resultVo;
	}

	@LogAnnotation(moduleName=LogConstant.MODULE_INQUIRY, option=LogConstant.AGENT_QUERY, logType=LogConstant.LOG_QUERY, content="代理查询信用报告")
	@Override
	public synchronized ResultVo<ResInquiryVo> addAgent(AgentVo record, HttpServletRequest request) {

		ResultVo<ResInquiryVo> resultVo = new ResultVo<>();
		
		if(record == null || StrUtil.isNull(record.getUserName(), record.getCardNum())){
			
			logger.error(LogUtil.msg("InquiryServiceImpl:addAgent", "请求参数正确"));
			
			resultVo.setCode(CodeConstant.REQ_PARAM_FAIL);
			resultVo.setMsg("请求参数不正确");
			return resultVo;
		}
		
        UserModel userModel = UserUtil.getUserModel(record.getSid(), redisService);
		
		if(StrUtil.isNull(userModel.getRealUserId())){

			logger.error(LogUtil.msg("InquiryServiceImpl:addAgent", "该账户没有关联真实用"));
			
			resultVo.setCode(CodeConstant.FAIL);
			resultVo.setMsg("该账户没有关联征信中心用户，不能查询，请与管理员联系");
			return resultVo;
		}
		/**
		 *           行路难 其一
		 *                       李白
		 * 金樽清酒斗十千，玉盘珍羞直万钱。
		 * 停杯投箸不能食，拔剑四顾心茫然。
		 * 欲渡黄河冰塞川，将登太行雪满山。
		 * 闲来垂钓碧溪上，忽复乘舟梦日边。
		 * 行路难，行路难，多岐路，今安在？
		 * 长风破浪会有时，直挂云帆济沧海。
		 */
		if(! checkLimitCount(record.getSid())){
			
			resultVo.setCode(ResCode.FAIL);
			resultVo.setMsg("当天的查询次数超限");
			return resultVo;
		}
		
		if(StrUtil.isNotNull(redisService.get(record.getCardNum()))){
			resultVo.setCode(ResCode.FAIL);
			resultVo.setMsg("不准在5分钟之内查询同一用户征信信息");
			return resultVo;
		}
		record.setInquiryType(CommonConstant.INQUIRY_TYPE_AGENT);
		
		ReqFirstStepVo reqFirstStepVo = InquiryUtil.getReqFirstStepForAgent(record);
		
		ResCCUserVo resCCUserVo = InquiryUtil.getResCCUserVo(request, redisService, realUserService);
		if(StrUtil.isNull(ConfConstant.ccTestPath) && resCCUserVo == null){
			
			logger.error(LogUtil.msg("InquiryServiceImpl:addAgent", "登录征信中心失败", JSON.toJSONString(record), record.getIp()));
			resultVo.setCode(CodeConstant.FAIL);
			resultVo.setMsg("查询失败（不能登录征信中心）");
			return resultVo;		
		}
		
		if(resCCUserVo != null){
			reqFirstStepVo.setCookies(resCCUserVo.getCookies());
		}
		
		ResultVo<ResFirstStepVo> resultFirstStep = ccQueryService.queryFirstStep(reqFirstStepVo, request);
		
		if(CodeConstant.CREDIT_NO_LOGIN.equals(resultFirstStep.getCode())){
			resCCUserVo = InquiryUtil.loginCCUser(userModel, redisService, realUserService, request);
			if(resCCUserVo != null){
				reqFirstStepVo.setCookies(resCCUserVo.getCookies());
				resultFirstStep = ccQueryService.queryFirstStep(reqFirstStepVo, request);
				
			}
		}
		if(! CodeConstant.SUCCESS.equals(resultFirstStep.getCode())){
			
			logger.error(LogUtil.msg("InquiryServiceImpl:addAgent", "查询征信中心失败", JSON.toJSONString(record), record.getIp()));
			resultVo.setCode(resultFirstStep.getCode());
			resultVo.setMsg("请求查询征信中心失败");
			return resultVo;
		}
		
		record.setIsCharge(resultFirstStep.getData().getIsFee());
		record.setInquiryIp(NetHelper.getIpAddr(request));
		try {
			
			int flag = 0;
			
			if(StrUtil.isNotNull(record.getId())){
				
				record.setInquiryId(record.getId());
				record.setUpdateBy(userModel.getUserId());
				record.setUpdateTime(new Date());
				flag = agentApi.update(record);
				
			} else {
				
				record.setId(PrimaryUtil.primaryId("I"));
				record.setOperationTime(new Date());
				record.setOperatorId(userModel.getUserId());				
				record.setInquiryId(record.getId());
				record.setStatus(0);
				record.setApproverId(userModel.getUserId());
				record.setApprovalTime(new Date());
				record.setCreateBy(userModel.getUserId());
				record.setCreateTime(new Date());
				record.setDeptId(userModel.getDeptId());
				record.setCorpId(userModel.getCorpId());
				flag = agentApi.insert(record);
			}
			if(flag == 0){
				resultVo.setCode(CodeConstant.FAIL);
				resultVo.setMsg("查询失败，添加查询记录出错");
				logger.error(LogUtil.msg("InquiryServiceImpl:addAgent", "添加或更新数据库失败"));
				return resultVo;
			}
		} catch (Exception e) {
			
			resultVo.setCode(CodeConstant.EXCEPTION);
			resultVo.setMsg("查询失败，添加查询记录出错");
			logger.error(LogUtil.msg("InquiryServiceImpl:addAgent", "添加或更新数据库失败"), e);
			return resultVo;
		}

		
		ResInquiryVo resInquiryVo = new ResInquiryVo();
		resInquiryVo.setId(record.getId());
		resInquiryVo.setFirstStepVo(resultFirstStep.getData());
		
		resultVo.setData(resInquiryVo);
		resultVo.setCode(CodeConstant.SUCCESS);
		return resultVo;
	}

	@LogAnnotation(moduleName=LogConstant.MODULE_INQUIRY, option=LogConstant.JUSTICE_QUERY, logType=LogConstant.LOG_QUERY, content="司法查询信用报告")
	@Override
	public synchronized ResultVo<ResCCJusticeVo> addJustice(JusticeVo record, HttpServletRequest request) {

		ResultVo<ResCCJusticeVo> resultVo = new ResultVo<>();
		
		if(record == null || StrUtil.isNull(record.getUserName(), record.getCardNum())){
			
			logger.error(LogUtil.msg("InquiryServiceImpl:addJustice", "请求参数正确"));
			
			resultVo.setCode(CodeConstant.REQ_PARAM_FAIL);
			resultVo.setMsg("请求参数不正确");
			return resultVo;
		}

		UserModel userModel = UserUtil.getUserModel(record.getSid(), redisService);
		
		if(StrUtil.isNull(userModel.getRealUserId())){

			logger.error(LogUtil.msg("InquiryServiceImpl:addJustice", "该账户没有关联真实用"));
			
			resultVo.setCode(CodeConstant.FAIL);
			resultVo.setMsg("该账户没有关联征信中心用户，不能查询，请与管理员联系");
			return resultVo;
		}
		if(! checkLimitCount(record.getSid())){
			
			resultVo.setCode(ResCode.FAIL);
			resultVo.setMsg("当天的查询次数超限");
			return resultVo;
		}
		
		if(StrUtil.isNotNull(redisService.get(record.getCardNum()))){
			resultVo.setCode(ResCode.FAIL);
			resultVo.setMsg("不准在5分钟之内查询同一用户征信信息");
			return resultVo;
		}
				
		record.setInquiryType(CommonConstant.INQUIRY_TYPE_JUSTICE);
		
		record.setInquiryIp(NetHelper.getIpAddr(request));
		try {
			
			int flag = 0;
				
			record.setId(PrimaryUtil.primaryId("I"));
			record.setOperationTime(new Date());
			record.setOperatorId(userModel.getUserId());				
			record.setInquiryId(record.getId());
			record.setStatus(1);
			record.setApproverId(userModel.getUserId());
			record.setApprovalTime(new Date());
			record.setCreateBy(userModel.getUserId());
			record.setCreateTime(new Date());
			record.setDeptId(userModel.getDeptId());
			record.setCorpId(userModel.getCorpId());
			flag = justiceApi.insert(record);
			
			
			if(flag == 0){
				resultVo.setCode(CodeConstant.FAIL);
				resultVo.setMsg("查询失败，添加查询记录出错");
				logger.error(LogUtil.msg("InquiryServiceImpl:addJustice", "添加或更新数据库失败"));
				return resultVo;
			}
			
		} catch (Exception e) {
			
			resultVo.setCode(CodeConstant.EXCEPTION);
			resultVo.setMsg("查询失败，添加查询记录出错");
			logger.error(LogUtil.msg("InquiryServiceImpl:addJustice", "添加或更新数据库失败"), e);
			return resultVo;
		}

		
		ReqCCJusticeVo reqCCJusticeVo = new ReqCCJusticeVo();
		reqCCJusticeVo.setCertno(record.getCardNum());
		reqCCJusticeVo.setCerttype(InquiryUtil.getCardType(record.getCardType()));
		reqCCJusticeVo.setName(record.getUserName());
		reqCCJusticeVo.setId(record.getId());
		
		ResCCUserVo resCCUserVo = InquiryUtil.getResCCUserVo(request, redisService, realUserService);
		if(StrUtil.isNull(ConfConstant.ccTestPath) && resCCUserVo == null){
			
			logger.error(LogUtil.msg("InquiryServiceImpl:addJustice", "登录征信中心失败", JSON.toJSONString(record), record.getIp()));
			resultVo.setCode(CodeConstant.FAIL);
			resultVo.setMsg("查询失败（不能登录征信中心）");
			return resultVo;		
		}
		
		if(resCCUserVo != null){
			reqCCJusticeVo.setCookies(resCCUserVo.getCookies());
		}
		
		ResultVo<ResCCJusticeVo> resultJustice = ccQueryService.justiceReport(reqCCJusticeVo, request);
		
		if(CodeConstant.CREDIT_NO_LOGIN.equals(resultJustice.getCode())){
			resCCUserVo = InquiryUtil.loginCCUser(userModel, redisService, realUserService, request);
			if(resCCUserVo != null){
				reqCCJusticeVo.setCookies(resCCUserVo.getCookies());
				resultJustice = ccQueryService.justiceReport(reqCCJusticeVo, request);
				
			}
		}
		
		if(! CodeConstant.SUCCESS.equals(resultJustice.getCode())){
			
			logger.error(LogUtil.msg("InquiryServiceImpl:addJustice", "查询征信中心失败", JSON.toJSONString(record), record.getIp()));
			resultVo.setCode(resultJustice.getCode());
			resultVo.setMsg("请求查询征信中心失败");
			updateQueryResult(record.getId(), "", 3, resultJustice.getMsg());
			return resultVo;
		}
		
		updateQueryResult(record.getId(), resultJustice.getData().getCreditNo(), 2, "");
		
		setQueryCount(request.getParameter("sid"));
		
		resultJustice.getData().setId(record.getId());
		
		return resultJustice;
	}

	@Override
	public synchronized ResultVo<ResCCApplyTblVo> toApplyTbl(ReqSecondStepVo vo, HttpServletRequest request) {

		ResultVo<ResCCApplyTblVo> resultVo = new ResultVo<>();
		
		if (vo == null || StrUtil.isNull(vo.getCertno(), vo.getId())) {

			logger.error(LogUtil.msg("InquiryServiceImpl:toApplyTbl", "请求参数正确"));
			resultVo.setCode(CodeConstant.REQ_PARAM_FAIL);
			resultVo.setMsg("请求参数不正确");
			return resultVo;
		}
		String name = "";
		String certNo = "";
		try {
			name = URLDecoder.decode(vo.getName(), "utf-8");
			certNo = URLDecoder.decode(vo.getCertno(), "utf-8");
			vo.setName(name);
			vo.setCertno(certNo);
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
		
		
		ResCCUserVo resCCUserVo = InquiryUtil.getResCCUserVo(request, redisService, realUserService);
		if(StrUtil.isNull(ConfConstant.ccTestPath) && resCCUserVo == null){
			
			logger.error(LogUtil.msg("InquiryServiceImpl:toApplyTbl", "登录征信中心失败", JSON.toJSONString(vo)));
			resultVo.setCode(CodeConstant.FAIL);
			resultVo.setMsg("查询失败（不能登录征信中心）");
			return resultVo;		
		}
		
		if(resCCUserVo != null){
			vo.setCookies(resCCUserVo.getCookies());
		}
		
		if(StrUtil.isNotNull(vo.getCerttype())){
			vo.setCerttype(InquiryUtil.getCardType(Integer.parseInt(vo.getCerttype())));
		}
		
		if(StrUtil.isNotNull(vo.getRelcerttype())){
			vo.setRelcerttype(InquiryUtil.getCardType(Integer.parseInt(vo.getRelcerttype())));
		}
		
		ResultVo<ResSecondStepVo>  resultSecond = ccQueryService.querySecondStep(vo, request);
		
		if (! CodeConstant.SUCCESS.equals(resultSecond.getCode())) {
			
			logger.error(LogUtil.msg("InquiryServiceImpl:toApplyTbl", "征信中心第二步查询失败 req=" + JSON.toJSONString(vo)));
			resultVo.setCode(CodeConstant.FAIL);
			resultVo.setMsg("获取征信中心申请表失败");
			return resultVo;
		}
		
		ResSecondStepVo resSecondStepVo = resultSecond.getData();
		
		ReqCCApplyTblVo reqCCApplyTblVo = InquiryUtil.getApplyTbl(vo);
		
		
		if(resCCUserVo != null){
			reqCCApplyTblVo.setCookies(resCCUserVo.getCookies());
		}
		
		reqCCApplyTblVo.setDissentid(resSecondStepVo.getDissentid());
		reqCCApplyTblVo.setCtype(CenterType.getName(vo.getCerttype()));
		reqCCApplyTblVo.setIdno(certNo);
		UserModel userModel = UserUtil.getUserModel(NetHelper.getReqParams(request, "sid", ""), redisService);
		
		reqCCApplyTblVo.setOpSignName(userModel.getSignName());
		reqCCApplyTblVo.setUser(name);
		
		ResCorpVo resCorpVo = corpApi.queryById(userModel.getCorpId());
		
		if(resCorpVo != null && "-1".equals(resCorpVo.getParentId())){
			reqCCApplyTblVo.setNote("中国人民银行征信中心广东省分中心");
		} else {
			reqCCApplyTblVo.setNote("中国人民银行征信中心广东省分中心（"+ resCorpVo.getName() +"）");
		}
		
		ResultVo<ResCCApplyTblVo> resuleApply = ccQueryService.applyTbl(reqCCApplyTblVo, request);
		
		if(! CodeConstant.SUCCESS.equals(resuleApply.getCode())){
			
			logger.error(LogUtil.msg("InquiryServiceImpl:toApplyTbl", "登录征信中心失败", JSON.toJSONString(vo)));
			resultVo.setCode(CodeConstant.FAIL);
			resultVo.setMsg("获取信用查询申请表失败");
			return resultVo;
		}
		
		ResCCApplyTblVo resCCApplyTblVo = resuleApply.getData();
		
		ApplyTblVo applyTblVo = new ApplyTblVo();
		applyTblVo.setId(PrimaryUtil.primaryId("A"));
		applyTblVo.setApplyContent(resCCApplyTblVo.getHtml());
		applyTblVo.setInquiryId(vo.getId());
		applyTblVo.setApplyType(1);
		applyTblVo.setCreateBy(userModel.getUserId());
		applyTblVo.setCreateTime(new Date());
		applyTblVo.setUpdateBy(userModel.getUserId());
		applyTblVo.setUpdateTime(new Date());
		
		InquiryVo inquiryVo = new InquiryVo();
		inquiryVo.setId(vo.getId());
		inquiryVo.setApplyNo(resCCApplyTblVo.getApplyNo());
		inquiryVo.setChargeNo(resSecondStepVo.getChargeNo());
		
		try {
			
			inquiryApi.update(inquiryVo);
			applyTblApi.insert(applyTblVo);
			
		} catch (Exception e) {
			logger.error(LogUtil.msg("InquiryServiceImpl:toApplyTbl", "更新查询表失败inquiryVo：" + JSON.toJSONString(inquiryVo)), e);
		}
		
		if(StrUtil.isNotNull(vo.getRelcertno())){
		
			executor.execute(new Runnable() {
				
				@Override
				public void run() {
					//添加新用户成功后在notice表插入新数据等待审核
					NoticeVo noticeVo=new NoticeVo();
					noticeVo.setId(PrimaryUtil.primaryId("R"));
					noticeVo.setSourceId(vo.getId());
					noticeVo.setCorpId(userModel.getCorpId());
					noticeVo.setContent("代理查询申请");
					//noticeVo.setNoticeUserId(noticeUserId);
					noticeVo.setNoticeType(CommonConstant.NOTICE_TYPE_ANEGT_INQUIRY);
					noticeVo.setNoticeFlag(1);
					noticeVo.setStatus(1);
					noticeVo.setApproveStatus(0);
					noticeVo.setCreateBy(userModel.getUserId());
					noticeVo.setCreateTime(new Date());
					noticeVo.setUpdateBy(userModel.getUserId());
					noticeVo.setUpdateTime(new Date());
					try {
						noticeApi.insert(noticeVo);
					} catch (Exception e) {
						logger.error(LogUtil.msg("InquiryServiceImpl:toApplyTbl", "添加通知信息异常"), e);
					}
					
				}
			});
		}
		resCCApplyTblVo.setCerttype(resSecondStepVo.getCerttype());
		resCCApplyTblVo.setChargeNO(resSecondStepVo.getChargeNo());
		resCCApplyTblVo.setDissentid(resSecondStepVo.getDissentid());
		resCCApplyTblVo.setQueryreason(resSecondStepVo.getQueryreason());
		resCCApplyTblVo.setVertype(resSecondStepVo.getVertype());
		resuleApply.setData(resCCApplyTblVo);
		
		return resuleApply;
	}

	@Override
	public synchronized ResultVo<ResCCCreditReportVo> creditReport(ReqCCCreditReportVo vo, HttpServletRequest request) {

		ResultVo<ResCCCreditReportVo> resultVo = new ResultVo<>();
		
		if (vo == null || StrUtil.isNull(vo.getCertno(), vo.getId())) {

			logger.error(LogUtil.msg("InquiryServiceImpl:creditReport", "请求参数正确"));
			resultVo.setCode(CodeConstant.REQ_PARAM_FAIL);
			resultVo.setMsg("请求参数不正确");
			return resultVo;
		}
		
		if(StrUtil.isNotNull(redisService.get(vo.getCertno()))){
			resultVo.setCode(ResCode.FAIL);
			resultVo.setMsg("不准在5分钟之内查询同一用户征信信息");
			return resultVo;
		}
		
		ResInquiryVo resInquiryVo = inquiryApi.queryById(vo.getId());
		
		if(resInquiryVo.getStatus() == 0){
			
			logger.info(LogUtil.msg("InquiryServiceImpl:creditReport", "经征信管理科负责人未审批"));
			resultVo.setCode(CodeConstant.FAIL);
			resultVo.setMsg("经征信管理科负责人未审批,请等待");
			return resultVo;
		}
		
		ResCCUserVo resCCUserVo = InquiryUtil.getResCCUserVo(request, redisService, realUserService);
		if(StrUtil.isNull(ConfConstant.ccTestPath) && resCCUserVo == null){
			
			logger.error(LogUtil.msg("InquiryServiceImpl:creditReport", "登录征信中心失败", JSON.toJSONString(vo)));
			resultVo.setCode(CodeConstant.FAIL);
			resultVo.setMsg("查询失败（不能登录征信中心）");
			return resultVo;		
		}
		
		if(resCCUserVo != null){
			vo.setCookies(resCCUserVo.getCookies());
		}
		
		vo.setCerttype(InquiryUtil.getCardType(Integer.parseInt(vo.getCerttype())));
		try {
			vo.setCertno(URLDecoder.decode(vo.getCertno(), "utf-8"));
			vo.setName(URLDecoder.decode(vo.getName(), "utf-8"));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		resultVo = ccQueryService.creditReport(vo, request);
		
		if(! CodeConstant.SUCCESS.equals(resultVo.getCode())){
			
			logger.error(LogUtil.msg("InquiryServiceImpl:creditReport", "查询征信中心失败", JSON.toJSONString(vo)));
			resultVo.setMsg("请求查询征信中心失败");
			updateQueryResult(vo.getId(), "", 3, resultVo.getMsg());
			return resultVo;
		} 
		
		updateQueryResult(vo.getId(), resultVo.getData().getCreditNo(), 2, "");
		
		DictionaryVo dictionaryVo = new DictionaryVo();
		dictionaryVo.setKeyword("QUERY_INTERVAL_TIME");
		ResultVo<ResDictionaryVo> resultDic = dictionaryService.getDicByKeyword(dictionaryVo, request);
		int timeout = 5*60;
		if(CodeConstant.SUCCESS.equals(resultDic.getCode())){
			timeout = Integer.parseInt(resultDic.getData().getDicValue()) * 60;
		}
		
		redisService.set(vo.getCertno(), vo.getId(), timeout);
		
		setQueryCount(request.getParameter("sid"));
		
		return resultVo;
	}
	
	@Override
	public ResultVo<ResInquiryVo> printReport(InquiryVo vo, HttpServletRequest request) {
		
		
		ResultVo<ResInquiryVo> resultVo = new ResultVo<>();
		
		if (vo == null || StrUtil.isNull(vo.getId())) {

			logger.error(LogUtil.msg("InquiryServiceImpl:printReport", "请求参数正确"));
			resultVo.setCode(CodeConstant.REQ_PARAM_FAIL);
			resultVo.setMsg("请求参数不正确");
			return resultVo;
		}
		
		ResInquiryVo resInquiryVo = inquiryApi.queryById(vo.getId());
		
		if(resInquiryVo == null){
			
			logger.error(LogUtil.msg("InquiryServiceImpl:printReport", "查询数据不存在"));
			resultVo.setCode(CodeConstant.DATA_NOT_EXSIT);
			resultVo.setMsg("数据不存在");
			return resultVo;
		}
		
		InquiryVo inquiryVo = new InquiryVo();
		inquiryVo.setId(vo.getId());
		if(inquiryVo.getPrintResult() == null || inquiryVo.getPrintResult() == 1){
			if(vo.getPrintResult() != -1){
				int printCount = resInquiryVo.getPrintCount() == null ? 0 : resInquiryVo.getPrintCount();
				inquiryVo.setPrintCount(printCount + 1);
			}
		}
		if(vo.getPrintResult() == -1){//取消
			if(resInquiryVo.getChargeResult() == null){
			  inquiryVo.setPrintResult(vo.getPrintResult());
			}
		} else {
			inquiryVo.setPrintResult(vo.getPrintResult());
		}
		
		try {
			inquiryApi.update(inquiryVo);
		} catch (Exception e) {
			logger.error(LogUtil.msg("InquiryServiceImpl:printReport", "更新打印次数异常"), e);
		}
		
		resultVo.setCode(CodeConstant.SUCCESS);
		return resultVo;
	}
	
	@Override
	public ResultVo<ResInquiryVo> find(InquiryVo record, HttpServletRequest request) {

		ResultVo<ResInquiryVo> resultVo = new ResultVo<>();
		resultVo.setCode(CodeConstant.FAIL);
		ResInquiryVo resInquiryVo = inquiryApi.query(record);
		if(resInquiryVo != null){
			String cardType = InquiryUtil.getCardType(resInquiryVo.getCardType());
			resInquiryVo.setCardName(CenterType.getName(cardType));
			if(resInquiryVo.getAgentVo() != null){
				String agentCardType = InquiryUtil.getCardType(resInquiryVo.getAgentVo().getAgentCardType());
				resInquiryVo.getAgentVo().setAgentCardName(CenterType.getName(agentCardType));
			}
			
			if(resInquiryVo.getJusticeVo() != null){
				String justiceCardType1 = InquiryUtil.getCardType(resInquiryVo.getJusticeVo().getJusticeCardType1());
				String justiceCardType2 = InquiryUtil.getCardType(resInquiryVo.getJusticeVo().getJusticeCardType2());
				resInquiryVo.getJusticeVo().setJusticeCardName1(CenterType.getName(justiceCardType1));
				resInquiryVo.getJusticeVo().setJusticeCardName2(CenterType.getName(justiceCardType2));
			}
			
			resultVo.setCode(CodeConstant.SUCCESS);
			resultVo.setData(resInquiryVo);
		}
		
		return resultVo;
	}
	
	private void updateQueryResult(String id, String creditNo, int result, String errorMsg){
		
		InquiryVo inquiryVo = new InquiryVo();
		inquiryVo.setReportNum(creditNo);
		inquiryVo.setStatus(result);
		inquiryVo.setId(id);
		try {
			inquiryApi.update(inquiryVo);
		} catch (Exception e) {
			logger.error(LogUtil.msg("InquiryServiceImpl:creditReport", "更新查询表失败inquiryVo：" + JSON.toJSONString(inquiryVo)), e);
		}
		
		executor.execute(new Runnable() {
			
			@Override
			public void run() {
				
				LogInquiryVo logInquiryVo = new LogInquiryVo();
				logInquiryVo.setInquiryId(id);
				logInquiryVo.setQueryResult(result + "");
				logInquiryVo.setReportCode(creditNo);
				logInquiryVo.setNote(errorMsg);
				try {
					logInquiryApi.update(logInquiryVo);
				} catch (Exception e) {
					logger.error(LogUtil.msg("InquiryServiceImpl:creditReport", "更新查询日志失败logInquiryVo：" + JSON.toJSONString(logInquiryVo)), e);
				}
				
			}
		});
		
	}

	@Override
	public ResultVo<ResApplyTblVo> updateApplyTbl(ApplyTblVo vo, HttpServletRequest request) {
		
		ResultVo<ResApplyTblVo> resultVo = new ResultVo<>();
		resultVo.setCode(CodeConstant.SUCCESS);
		UserModel userModel = UserUtil.getUserModel(request.getParameter("sid"), redisService);
		vo.setOpSignInfo(userModel.getSignName());
		try {
			applyTblApi.update(vo);
		} catch (Exception e) {
			resultVo.setCode(CodeConstant.EXCEPTION);
			logger.error(LogUtil.msg("InquiryServiceImpl:creditReport", "修改申请表失败：" + JSON.toJSONString(vo)), e);
			resultVo.setMsg("修改申请表异常");
		}
		
		return resultVo;
	}

	@Override
	public ResultVo<ResApplyTblVo> findApplyTbl(ApplyTblVo vo, HttpServletRequest request) {
		
	
		ResApplyTblVo resApplyTblVo = applyTblApi.query(vo);
		String html = "";
		if(resApplyTblVo != null){
			Document document = Jsoup.parse(resApplyTblVo.getApplyContent());
			
			Element userSign =   document.getElementById("userNameImg");//opSignNameImg
			if (userSign != null) {
				userSign.removeAttr("style");
				userSign.attr("src", "data:image/png;base64," + resApplyTblVo.getSignInfo());
			}
			
			Element opSign =   document.getElementById("opSignNameImg");
			if (opSign != null) {
				opSign.attr("src", "data:image/png;base64," + resApplyTblVo.getOpSignInfo());
			}
			
			html = document.html();
		}
		
		ResultVo<ResApplyTblVo> resultVo = new ResultVo<>();
		resApplyTblVo.setApplyContent(html);
		resultVo.setData(resApplyTblVo);
		resultVo.setCode(ResCode.SUCCESS);
		
		return resultVo;
	}
	
	private void setQueryCount(String sid){

		UserModel userModel = UserUtil.getUserModel(sid, redisService);
		String key = userModel.getUserId() + "_" + DateUtil.format(new Date(), DateUtil.FORMAT_DAY);
		String value = redisService.get(key);
		Integer count = 0;
		if(StrUtil.isNotNull(value)){
			count = Integer.parseInt(value.toString());
		}
		
		count ++;
		
		redisService.set(key, count.toString(), 12*60*60);
		//redisService.set(userModel.getUserId() + "_" + DateUtil.format(new Date(), format), value)
	}
		
	private boolean checkLimitCount(String sid){
		
		UserModel userModel = UserUtil.getUserModel(sid, redisService);
		
		String curDay = DateUtil.format(new Date(), DateUtil.FORMAT_DAY);
		
		String key = userModel.getUserId() + "_" + curDay;
		String value = redisService.get(key);
		
		if(StrUtil.isNull(value)){
			return true;
		}
		
		int queryCount = Integer.parseInt(value.toString());
		if(queryCount >= userModel.getLimitCount()){
			logger.error(LogUtil.msg("InquiryServiceImpl:chechLimitCount","当日查询次数超限，" + curDay +  "的查询次数为：" + 
		                        queryCount + ", 当日查询次数限制为：" + userModel.getLimitCount()));
			return false;
		}
		
		return true;
		
	}

	@Override
	public ResultVo<Boolean> checkLimitQuery(InquiryVo vo, HttpServletRequest request) {

		boolean flag = checkLimitCount(request.getParameter("sid"));
		ResultVo<Boolean> resultVo = new ResultVo<>();
		resultVo.setCode(CodeConstant.SUCCESS);
		if(! flag){
			resultVo.setMsg("今日查询次数超限，如有需要增加查询次数，请与管理员联系");
		}
		resultVo.setData(flag);
		return resultVo;
	}

	@Override
	public ResultVo<ResCCCreditReportVo> againPrintReport(ReqCCCreditReportVo vo, HttpServletRequest request) {

		ResultVo<ResCCCreditReportVo> resultVo = new ResultVo<>();
		
		if (vo == null || StrUtil.isNull(vo.getCertno(), vo.getQueryreason(), vo.getName())) {

			logger.error(LogUtil.msg("InquiryServiceImpl:againPrintReport", "请求参数正确"));
			resultVo.setCode(CodeConstant.REQ_PARAM_FAIL);
			resultVo.setMsg("请求参数不正确");
			return resultVo;
		}
		
		String queryId = redisService.get(vo.getCertno());
		
		if(StrUtil.isNull(queryId)){
			resultVo.setCode(ResCode.FAIL);
			logger.error(LogUtil.msg("InquiryServiceImpl:againPrintReport", "缓存中没有该用户的补打报告信息"));
			resultVo.setMsg("只能补打5分钟以内查询的征信报告");
			return resultVo;
		}
		
		ResInquiryVo resInquiryVo = inquiryApi.queryById(queryId);
		
		if(resInquiryVo == null){
			
			logger.info(LogUtil.msg("InquiryServiceImpl:againPrintReport", "没有发现该用户的补打报告数据"));
			resultVo.setCode(CodeConstant.FAIL);
			resultVo.setMsg("没有发现该用户补打的报告数据");
			return resultVo;
		}
		
		if(resInquiryVo.getPrintResult() == 2 || resInquiryVo.getPrintResult() == 3){
			
			logger.info(LogUtil.msg("InquiryServiceImpl:againPrintReport", "该报告已打印过，不能补打"));
			resultVo.setCode(CodeConstant.FAIL);
			resultVo.setMsg("该报告已打印过，不能补打");
			return resultVo;
		}
		
		vo.setCerttype(InquiryUtil.getCardType(Integer.parseInt(vo.getCerttype())));
		try {
			vo.setCertno(URLDecoder.decode(vo.getCertno(), "utf-8"));
			vo.setName(URLDecoder.decode(vo.getName(), "utf-8"));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		
		vo.setVertype("24");
		
		if (resInquiryVo.getFormat() == 1) {
			vo.setVertype("21");
		}
		
		vo.setId(queryId);
		resultVo = ccQueryService.againPrintReport(vo, request);
		
		if(! CodeConstant.SUCCESS.equals(resultVo.getCode())){
			
			logger.error(LogUtil.msg("InquiryServiceImpl:againPrintReport", "查询补打报告失败", JSON.toJSONString(vo)));
			resultVo.setMsg("查询补打报告失败");
			return resultVo;
		} 
		UserModel userModel = UserUtil.getUserModel(request.getParameter("sid"), redisService);
		
		InquiryVo inquiryVo = new InquiryVo();
		inquiryVo.setId(vo.getId());
		inquiryVo.setPrintResult(3);
		inquiryVo.setNote(vo.getQueryreason());
		inquiryVo.setUpdateBy(userModel.getUserId());
		inquiryVo.setUpdateTime(new Date());
		try {
			inquiryApi.update(inquiryVo);
		} catch (Exception e) {
			logger.error(LogUtil.msg("InquiryServiceImpl:againPrintReport", "更新补打结果异常"), e);
		}
		
		return resultVo;

	}
}
